import random
from datetime import datetime
from dao.questions_dao import QuestionDAO
from dao.practice_progress_dao import PracticeProgressDAO
from dao.error_questions_dao import ErrorQuestionDAO
from models.practice_progress import PracticeProgress
from models.error_question import ErrorQuestion
from utils.logger import Logger

class PracticeService:
    def __init__(self):
        self.questions_dao = QuestionDAO()
        self.practice_progress_dao = PracticeProgressDAO()
        self.error_questions_dao = ErrorQuestionDAO()
        self.logger = Logger()
        
    def get_questions_by_category(self, category):
        """根据类别获取题目"""
        # 根据类别字段获取题目 (LA, LB, LC)
        sql = f"SELECT * FROM questions WHERE L{category} = 1"
        return self.questions_dao._execute_query(sql, ())
        
    def get_error_questions(self, user_id, category):
        """
        根据用户ID和类别获取错题，并关联查询题目详情
        :param user_id: 用户ID
        :param category: 类别
        :return: 关联后的错题对象列表
        """
        return self.error_questions_dao.get_error_questions_with_details(user_id, category)
        
    def shuffle_options(self, questions):
        """打乱题目选项并更新正确答案"""
        for question in questions:
            # 保存原始选项和正确答案
            original_options = {'A': question.A, 'B': question.B, 'C': question.C, 'D': question.D}
            correct_answer = question.T

            # 创建选项列表(保留键值对)并打乱
            options = list(original_options.items())
            random.shuffle(options)

            # 重新赋值打乱后的选项
            question.A, question.B, question.C, question.D = [opt[1] for opt in options[:4]]

            # 创建原始选项到新选项的映射
            original_to_new = {opt[0]: chr(65 + i) for i, opt in enumerate(options)}

            # 更新正确答案
            new_correct = ''
            for char in correct_answer:
                # 过滤掉非字母字符(如空格)
                if char.isalpha():
                    new_correct += original_to_new[char]

            # 对新的正确答案进行排序（多选题）
            if len(new_correct) > 1:
                new_correct = ''.join(sorted(new_correct))

            question.T = new_correct
        
        return questions
        
    def get_practice_progress(self, user_id, category):
        """获取练习进度"""
        progress = self.practice_progress_dao.get_by_user_and_category(user_id, category)
        if progress:
            return progress.current_index
        return 0
        
    def save_practice_progress(self, user_id, category, index):
        """保存练习进度"""
        # 检查是否已存在进度记录
        progress = self.practice_progress_dao.get_by_user_and_category(user_id, category)
        if progress:
            # 更新现有记录
            self.practice_progress_dao.update_by_user_and_category(
                user_id, category, current_index=index, last_accessed=datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            )
        else:
            # 创建新记录
            new_progress = PracticeProgress(
                user_id=user_id,
                category=category,
                current_index=index,
                last_accessed=datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            )
            self.practice_progress_dao.create(new_progress)

    def add_error_question(self, question_id, category, user_id):
        """添加错题到错题本"""
        # 检查题目是否已存在于错题本
        existing_error = self.error_questions_dao.get_by_user_question_and_category(user_id, question_id, category)
        if not existing_error:
            # 创建错题实体
            error_question = ErrorQuestion(
                question_id=question_id,
                category=category,
                user_id=user_id
            )
            # 添加新错题
            result = self.error_questions_dao.create(error_question)
            if result is not None:
                self.logger.info(f"将题目{question_id}添加到用户{user_id}的{category}类别错题本成功，ID: {result}")
                return True
            else:
                self.logger.error(f"将题目{question_id}添加到用户{user_id}的{category}类别错题本失败")
                return False
        else:
            self.logger.info(f"题目{question_id}已存在于用户{user_id}的{category}类别错题本")
            return False
